--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
nomadnet/util.py 02a0a260b8b4b84658d7f50acaf01e03d2e1b8c6 (02a0a260) Text, 6.59 KB
Tff7b72import T7ee787re
Tff7b72import T7ee787unicodedata
Te6edf3invalid_rendering Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffπ΅οΈTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffβTa5d6ff"Tb4b4b4]
T8b949e# Unicode blocks to strip (symbols, dingbats, emoji ranges)
Te6edf3STRIP_BLOCKS_RE Tff7b72= Te6edf3reTff7b72.Td2a8ffcompileTb4b4b4(
Ta5d6ff'Ta5d6ff[Ta5d6ff'
Ta5d6ff'Tffea00\U0001F600Ta5d6ff-Tffea00\U0001F64FTa5d6ff' T8b949e# Emoticons
Ta5d6ff'Tffea00\U0001F300Ta5d6ff-Tffea00\U0001F5FFTa5d6ff' T8b949e# Misc Symbols & Pictographs
Ta5d6ff'Tffea00\U0001F680Ta5d6ff-Tffea00\U0001F6FFTa5d6ff' T8b949e# Transport & Map Symbols
Ta5d6ff'Tffea00\U0001F700Ta5d6ff-Tffea00\U0001F77FTa5d6ff' T8b949e# Alchemical Symbols
Ta5d6ff'Tffea00\U0001F780Ta5d6ff-Tffea00\U0001F7FFTa5d6ff' T8b949e# Geometric Shapes Extended
Ta5d6ff'Tffea00\U0001F800Ta5d6ff-Tffea00\U0001F8FFTa5d6ff' T8b949e# Supplemental Arrows-C
Ta5d6ff'Tffea00\U0001F900Ta5d6ff-Tffea00\U0001F9FFTa5d6ff' T8b949e# Supplemental Symbols & Pictographs
Ta5d6ff'Tffea00\U0001FA00Ta5d6ff-Tffea00\U0001FA6FTa5d6ff' T8b949e# Chess Symbols
Ta5d6ff'Tffea00\U0001FA70Ta5d6ff-Tffea00\U0001FAFFTa5d6ff' T8b949e# Symbols & Pictographs Extended-A
Ta5d6ff'Tffea00\U0001F1E0Ta5d6ff-Tffea00\U0001F1FFTa5d6ff' T8b949e# Flags (iOS/regional indicators)
Ta5d6ff'Tffea00\u2600Ta5d6ff-Tffea00\u26FFTa5d6ff' T8b949e# Misc Symbols (β, β, β, etc.)
Ta5d6ff'Tffea00\u2700Ta5d6ff-Tffea00\u27BFTa5d6ff' T8b949e# Dingbats (β, β, β, β, etc.)
Ta5d6ff'Tffea00\uFE00Ta5d6ff-Tffea00\uFE0FTa5d6ff' T8b949e# Variation Selectors
Ta5d6ff'Tffea00\U000E0100Ta5d6ff-Tffea00\U000E01EFTa5d6ff' T8b949e# Variation Selectors Supplement
Ta5d6ff'Tffea00\U0001F3FBTa5d6ff-Tffea00\U0001F3FFTa5d6ff' T8b949e# Emoji modifiers (skin tones)
Ta5d6ff'Ta5d6ff]+Ta5d6ff'Tb4b4b4,
Te6edf3flagsTff7b72=Te6edf3reTff7b72.Td2a8ffUNICODE
Tb4b4b4)
T8b949e# Control characters and zero-width characters to strip
Te6edf3STRIP_CONTROL_RE Tff7b72= Te6edf3reTff7b72.Td2a8ffcompileTb4b4b4(
Ta5d6ff'Ta5d6ff[Ta5d6ff'
Ta5d6ff'Tffea00\x00Ta5d6ff-Tffea00\x08Ta5d6ff' T8b949e# C0 controls (NUL-BS)
Ta5d6ff'Tffea00\x0BTffea00\x0CTa5d6ff' T8b949e# VT, FF
Ta5d6ff'Tffea00\x0ETa5d6ff-Tffea00\x1FTa5d6ff' T8b949e# C0 controls (SO-US)
Ta5d6ff'Tffea00\x7FTa5d6ff-Tffea00\x9FTa5d6ff' T8b949e# DEL and C1 controls
Ta5d6ff'Tffea00\u200BTa5d6ff-Tffea00\u200FTa5d6ff' T8b949e# Zero-width chars, LRM, RLM, etc.
Ta5d6ff'Tffea00\u202ATa5d6ff-Tffea00\u202ETa5d6ff' T8b949e# Bidi embedding controls
Ta5d6ff'Tffea00\u2060Ta5d6ff-Tffea00\u206FTa5d6ff' T8b949e# Format chars (word joiner, etc.)
Ta5d6ff'Tffea00\uFEFFTa5d6ff' T8b949e# BOM / Zero Width NBSP
Ta5d6ff'Tffea00\uFFF0Ta5d6ff-Tffea00\uFFF8Ta5d6ff' T8b949e# Specials
Ta5d6ff'Ta5d6ff]+Ta5d6ff'Tb4b4b4,
Te6edf3flagsTff7b72=Te6edf3reTff7b72.Td2a8ffUNICODE
Tb4b4b4)
T8b949e# Surrogates and private use areas
T8b949e# Shouldn't appear in valid UTF-8, but strip just in case
Te6edf3STRIP_PRIVATE_RE Tff7b72= Te6edf3reTff7b72.Td2a8ffcompileTb4b4b4(
Ta5d6ff'Ta5d6ff[Ta5d6ff'
Ta5d6ff'Tffea00\uD800Ta5d6ff-Tffea00\uDFFFTa5d6ff' T8b949e# Surrogates
Ta5d6ff'Tffea00\uE000Ta5d6ff-Tffea00\uF8FFTa5d6ff' T8b949e# Private Use Area
Ta5d6ff'Tffea00\uF900Ta5d6ff-Tffea00\uFAFFTa5d6ff' T8b949e# CJK Compatibility Ideographs (keep? strip for safety)
Ta5d6ff'Tffea00\uFE10Ta5d6ff-Tffea00\uFE1FTa5d6ff' T8b949e# Vertical Forms
Ta5d6ff'Tffea00\uFE20Ta5d6ff-Tffea00\uFE2FTa5d6ff' T8b949e# Combining Half Marks
Ta5d6ff'Tffea00\U000F0000Ta5d6ff-Tffea00\U000FFFFFTa5d6ff' T8b949e# Supplementary Private Use Area-A
Ta5d6ff'Tffea00\U00100000Ta5d6ff-Tffea00\U0010FFFFTa5d6ff' T8b949e# Supplementary Private Use Area-B
Ta5d6ff'Ta5d6ff]+Ta5d6ff'Tb4b4b4,
Te6edf3flagsTff7b72=Te6edf3reTff7b72.Td2a8ffUNICODE
Tb4b4b4)
Tff7b72def Td2a8ffstrip_modifiersTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffprocess_charactersTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3result Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3i Tff7b72= T79c0ff0
Tff7b72while Te6edf3i Tff7b72< Tffa657lenTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3char Tff7b72= Te6edf3textTb4b4b4[Te6edf3iTb4b4b4]
Te6edf3category Tff7b72= Te6edf3unicodedataTff7b72.Td2a8ffcategoryTb4b4b4(Te6edf3charTb4b4b4)
Tff7b72if Te6edf3categoryTff7b72.Td2a8ffstartswithTb4b4b4(Tb4b4b4(Ta5d6ff'Ta5d6ffLTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffNTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffPTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffSTa5d6ff'Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Te6edf3charTb4b4b4)
Te6edf3i Tff7b72+Tff7b72= T79c0ff1
Tff7b72elif Te6edf3categoryTff7b72.Td2a8ffstartswithTb4b4b4(Tb4b4b4(Ta5d6ff'Ta5d6ffMTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffSkTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffCfTa5d6ff'Tb4b4b4)Tb4b4b4) Tff7b72or Te6edf3char Tff7b72in Ta5d6ff'Tffea00\u200dTffea00\u200cTa5d6ff'Tb4b4b4:
Te6edf3i Tff7b72+Tff7b72= T79c0ff1
Tff7b72elseTb4b4b4:
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Te6edf3charTb4b4b4)
Te6edf3i Tff7b72+Tff7b72= T79c0ff1
Tff7b72return Ta5d6ff'Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3resultTb4b4b4)
Tff7b72if Te6edf3text Tff7b72== Tff7b72NoneTb4b4b4: Tff7b72return Tff7b72None
Tff7b72for Te6edf3char Tff7b72in Te6edf3invalid_renderingTb4b4b4:
Te6edf3text Tff7b72= Te6edf3textTff7b72.Td2a8ffreplaceTb4b4b4(Te6edf3charTb4b4b4, Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3process_charactersTb4b4b4(Te6edf3textTb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff[Ta5d6ff\Ta5d6ffuFE00-Ta5d6ff\Ta5d6ffuFE0F]Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3strippedTb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff[Ta5d6ff\Ta5d6ffU000E0100-Ta5d6ff\Ta5d6ffU000E01EF]Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3strippedTb4b4b4, Te6edf3flagsTff7b72=Te6edf3reTff7b72.Td2a8ffUNICODETb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff[Ta5d6ff\Ta5d6ffU0001F3FB-Ta5d6ff\Ta5d6ffU0001F3FF]Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3strippedTb4b4b4, Te6edf3flagsTff7b72=Te6edf3reTff7b72.Td2a8ffUNICODETb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff[Ta5d6ff\Ta5d6ffu200DTa5d6ff\Ta5d6ffu200C]Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3strippedTb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff\Ta5d6ffrTa5d6ff\Ta5d6ffn?Ta5d6ff'Tb4b4b4, Ta5d6ff'Tffea00\nTa5d6ff'Tb4b4b4, Te6edf3strippedTb4b4b4)
Tff7b72return Te6edf3strippedTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffreplaceTb4b4b4(Ta5d6ff"Tffea00\x00Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffsanitize_nameTb4b4b4(Te6edf3nameTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3name Tff7b72is Tff7b72NoneTb4b4b4: Tff7b72return Tff7b72None
T8b949e# Convert to string and normalize to NFKC
T8b949e# NFKC: Compatibility decomposition followed by canonical composition
T8b949e# This handles: β to 1, β
to I, etc., while keeping composed forms
Te6edf3name Tff7b72= Tffa657strTb4b4b4(Te6edf3nameTb4b4b4)
Te6edf3name Tff7b72= Te6edf3unicodedataTff7b72.Td2a8ffnormalizeTb4b4b4(Ta5d6ff'Ta5d6ffNFKCTa5d6ff'Tb4b4b4, Te6edf3nameTb4b4b4)
T8b949e# Build result using category-based filtering
Te6edf3result Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3char Tff7b72in Te6edf3nameTb4b4b4:
Te6edf3cat Tff7b72= Te6edf3unicodedataTff7b72.Td2a8ffcategoryTb4b4b4(Te6edf3charTb4b4b4)
Te6edf3cat_prefix Tff7b72= Te6edf3catTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72if Te6edf3cat Tff7b72else Ta5d6ff'Ta5d6ffCTa5d6ff'
T8b949e# Allow letters (L*), numbers (N*), and punctuation (P*)
Tff7b72if Te6edf3cat_prefix Tff7b72in Tb4b4b4(Ta5d6ff'Ta5d6ffLTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffNTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffPTa5d6ff'Tb4b4b4)Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Te6edf3charTb4b4b4)
T8b949e# Allow space separator, normalize to regular space
Tff7b72elif Te6edf3cat Tff7b72== Ta5d6ff'Ta5d6ffZsTa5d6ff'Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4)
T8b949e# Convert line/paragraph separators to space
Tff7b72elif Te6edf3cat Tff7b72in Tb4b4b4(Ta5d6ff'Ta5d6ffZlTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ffZpTa5d6ff'Tb4b4b4)Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4)
T8b949e# Allow spacing combining marks (Mc) for Indic, Hebrew, etc.
Tff7b72elif Te6edf3cat Tff7b72== Ta5d6ff'Ta5d6ffMcTa5d6ff'Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Te6edf3charTb4b4b4)
T8b949e# Allow modifier letters (Lm) - e.g., Κ°, Κ±, Λ
Tff7b72elif Te6edf3cat Tff7b72== Ta5d6ff'Ta5d6ffLmTa5d6ff'Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Te6edf3charTb4b4b4)
T8b949e# Strip everything else:
T8b949e# - Mn (Nonspacing Mark): diacritics, combining marks (Zalgo)
T8b949e# - Me (Enclosing Mark): enclosing combining marks
T8b949e# - C* (Controls, Format, Surrogates, Private Use, Unassigned)
T8b949e# - S* (Symbols: currency, math, modifiers, other)
Te6edf3name Tff7b72= Ta5d6ff'Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3resultTb4b4b4)
T8b949e# Additional block-based stripping for symbols that categories missed
Te6edf3name Tff7b72= Te6edf3STRIP_BLOCKS_RETff7b72.Td2a8ffsubTb4b4b4(Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3nameTb4b4b4)
Te6edf3name Tff7b72= Te6edf3STRIP_CONTROL_RETff7b72.Td2a8ffsubTb4b4b4(Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3nameTb4b4b4)
Te6edf3name Tff7b72= Te6edf3STRIP_PRIVATE_RETff7b72.Td2a8ffsubTb4b4b4(Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3nameTb4b4b4)
T8b949e# Collapse multiple whitespace characters
Te6edf3name Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff\Ta5d6ffs+Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4, Te6edf3nameTb4b4b4)
T8b949e# Strip leading/trailing whitespace
Te6edf3name Tff7b72= Te6edf3nameTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3name
Tff7b72def Td2a8ffstrip_micronTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`[FB][0-9a-fA-F]Tffd700{3}Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`[FB]T[0-9a-fA-F]Tffd700{6}Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`[!*_=]Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`f`bTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`fTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`bTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`<Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`>Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff{Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Tff7b72return Te6edf3text
Tff7b72def Td2a8ffstrip_escaped_micronTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦[FB][0-9a-fA-F]Tffd700{3}Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦[FB]T[0-9a-fA-F]Tffd700{6}Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦[!*_=]Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦f`bTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦fTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦bTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦<Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦>Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦Ta5d6ff{Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Tff7b72return Te6edf3text
Tff7b72def Td2a8ffunescape_micronTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦([FB][0-9a-fA-F]Tffd700{3}Ta5d6ff)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦([FB]T[0-9a-fA-F]Tffd700{6}Ta5d6ff)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦([!*_=])Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦(f`b)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦(f)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦(b)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦(<)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦(>)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff¦(Ta5d6ff{Ta5d6ff)Ta5d6ff'Tb4b4b4, Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff\Ta5d6ff1Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Tff7b72return Te6edf3text
Tff7b72def Td2a8ffstrip_non_formatting_tagsTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`<Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`>Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`Ta5d6ff{Ta5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`rTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`cTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Te6edf3text Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff'Ta5d6ff`lTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff'Tb4b4b4, Te6edf3textTb4b4b4)
Tff7b72return Te6edf3text
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ